Skip to content

第2章 Spring Boot配置体系 ​

技术栈:Spring Boot 4.1.1 + JDK 17 本章定位:配置是Spring Boot的核心骨架,从端口调整、数据库连接、功能开关到多环境部署,全部基于配置体系完成。


学习目标 ​

  1. ✅ 掌握properties和YAML两种配置格式,能正确编写、互相转换,避开YAML语法坑
  2. ✅ 掌握三种配置读取方式:@Value、Environment、@ConfigurationProperties,知道各自适用场景
  3. ✅ 会用@PropertySource加载自定义配置、@ImportResource兼容XML配置、@Configuration+@Bean编写Java配置类
  4. ✅ 熟练掌握Profile多环境配置,会用多种方式切换环境
  5. ✅ 理解配置优先级、敏感信息处理、外置配置等企业级规范
  6. ✅ 能独立排查配置不生效、读取失败、中文乱码等常见问题

2.1 全局配置文件 ​

2.1.1 配置文件概述 ​

Spring Boot的核心设计思想是**「约定大于配置」**:框架提前约定了绝大多数场景的默认值,90%的情况你不用写任何配置,项目就能跑起来。只有需要修改默认行为时,才去全局配置文件里覆盖对应配置项。

Spring Boot启动时,会自动从src/main/resources目录下加载全局配置文件,支持两种格式:

  • application.properties:传统键值对格式
  • application.yml / application.yaml:YAML结构化格式

⚠️ 优先级规则:

  1. 同目录下同时存在时,properties > yml > yaml,高优先级的同名配置会覆盖低优先级的
  2. 不同的配置项会合并生效,不会互相覆盖

配置分为三类:

类型示例说明
Spring Boot内置配置server.port、spring.datasource.url框架自带的配置项,修改即可改变框架行为
第三方Starter配置mybatis.mapper-locations引入的第三方启动器提供的配置项
自定义业务配置app.upload-path开发者自己定义的配置,代码中读取使用

💡 新手提示:不用死记所有配置项,常用的记几个,其余用到的时候查官方文档即可。

官方配置参考:https://docs.spring.io/spring-boot/docs/4.1.1/reference/htmlsingle/#application-properties

2.1.2 application.properties 详解 ​

.properties是Java原生的配置格式,采用key=value的扁平结构,一行一个配置。

基础语法 ​

properties
# ===== 字符串 =====
# 注释用#号开头,默认不用加引号
app.name=springboot-demo
app.description=这是一个Spring Boot项目

# ===== 数字 =====
server.port=8080
app.max-connections=100

# ===== 布尔值 =====
app.enable-cache=true
app.debug=false

# ===== 对象/Map =====
# 用.分隔层级
user.id=1001
user.name=张三
user.age=25
user.email=zhangsan@example.com

# ===== 数组/List =====
# 写法1:逗号分隔
user.hobbies=读书,跑步,编程

# 写法2:按索引赋值
user.hobbies[0]=读书
user.hobbies[1]=跑步
user.hobbies[2]=编程

优缺点 ​

  • ✅ 优点:格式简单,所有Java项目都兼容
  • ❌ 缺点:配置多了之后,前缀大量重复,层级不清晰,可读性差

2.1.3 application.yml 详解(重点⭐) ​

YAML(YAML Ain't Markup Language)用空格缩进表示层级关系,结构清晰,是目前企业新项目的主流格式。

🔴 新手必记:四大语法铁则(错一个配置都不生效) ​

  1. key: value 冒号后面必须加空格,没空格直接失效
  2. 只能用空格缩进,绝对不能用Tab键,同一层级必须左对齐
  3. 大小写敏感,Name和name是两个完全不同的key
  4. #开头表示注释

❌ 新手头号坑:YAML语法错误不会报错!配置静默失效,启动不报错但就是读不到值,90%的配置问题都是缩进和空格的锅。

错误示例 vs 正确示例 ​

❌ 错误写法(典型新手错误)

server:
port:8080 # 错误:port没缩进;冒号后面没空格
  name:demo # 错误:name缩进和port不对齐

✅ 正确写法

yaml
server:
  port: 8080
  name: demo

基础语法示例 ​

1. 字面量 ​
yaml
# 字符串,默认不用加引号
app:
  name: springboot-demo
  description: 这是一个Spring Boot项目

# 数字
server:
  port: 8080

# 布尔值
app:
  enable-cache: true

引号说明:

  • 单引号' ':转义特殊字符,比如'\n'会被当成普通字符串\n
  • 双引号" ":不转义特殊字符,比如"\n"就是换行
  • 普通场景直接写,不用加引号
2. 对象/Map ​
yaml
# 缩进式(推荐,结构清晰)
user:
  id: 1001
  name: 张三
  age: 25
  email: zhangsan@example.com

# 行内式(适合简单对象)
user: {id: 1001, name: 张三, age: 25}
3. 数组/List ​
yaml
# 缩进式(推荐)
user:
  hobbies:
    - 读书
    - 跑步
    - 编程

# 行内式
user:
  hobbies: [读书, 跑步, 编程]

注意:短横线-前面要有缩进,后面必须加空格。

4. 多层嵌套(真实项目写法) ​
yaml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
  redis:
    host: localhost
    port: 6379
    timeout: 3000

mybatis:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true

在线转换工具 ​

复杂配置写完,可以用工具校验格式,避免缩进错误:

2.1.4 配置文件位置与优先级 ​

Spring Boot启动时,会从5个位置扫描配置文件,优先级从高到低,高优先级覆盖低优先级的同名配置:

优先级位置说明
1(最高)file:./config/JAR包同级目录下的config子目录(外部配置)
2file:./JAR包所在的同级目录(外部配置)
3classpath:/config/resources下的config目录(内部配置)
4(最低)classpath:/resources根目录(我们开发默认放的位置)

企业级实践:外置配置文件 ​

生产环境通常把配置文件放在JAR包外面,改配置不用重新打包,这是企业部署的标准操作。

目录结构:

myapp/
├── config/
│   └── application.yml   # 外部配置,优先级更高
└── myapp.jar          # 可执行JAR包

启动的时候直接java -jar myapp.jar,会自动优先读取外部config目录下的配置。修改配置只需要改外部文件,重启即可生效。

🔒 安全红线: 生产环境的数据库密码、第三方密钥等敏感信息,绝对不能写在代码里,也不能提交到Git。一般由运维人员管理外部配置文件,开发人员不接触生产环境密码。


2.2 配置绑定:代码中读取配置 ​

配置写好之后,怎么在Java代码里读取使用?主流有三种方式,各有适用场景。

2.2.1 @Value 注解(单个配置注入) ​

最简单的单个配置项注入,适合零散少量配置。

基础用法 ​

java
package com.example.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component // 必须交给Spring管理,不然注解不生效!
public class AppConfig {

    // 读取内置配置server.port
    @Value("${server.port}")
    private Integer port;

    // 读取自定义配置app.name
    @Value("${app.name}")
    private String appName;
}

设置默认值(必学⭐) ​

配置不存在的时候,给一个默认值,用冒号:分隔,避免启动报错。

java
// app.name不存在时,默认值为default-app
@Value("${app.name:default-app}")
private String appName;

// 数字默认值
@Value("${app.max-connections:100}")
private Integer maxConnections;

⚠️ 新手踩坑:@Value("${app.name}")如果配置文件里没有app.name,会直接抛出PlaceholderResolutionException,项目启动失败!所以写@Value建议都加上默认值。

支持SpEL表达式 ​

支持Spring表达式语言,可以做简单运算、调用方法:

java
// 生成随机数
@Value("#{T(java.lang.Math).random() * 100}")
private Double randomNum;

// 字符串分割
@Value("#{'${user.hobbies}'.split(',')}")
private String[] hobbies;

优缺点 ​

✅优点❌缺点
简单直接,单个配置注入方便配置多的时候代码繁琐
支持SpEL表达式不支持批量绑定、不支持JSR303校验
复杂对象注入麻烦

🎯 适用场景:只需要读取少量零散配置项的时候。

java
package com.example.demo.controller;

@RestController
@RequestMapping("/test")
public class ConfigTestController {

    // 注入我们写的配置类
    @Autowired
    private AppConfig appConfig;

    @GetMapping("/config1")
    public String getConfig1() {
        return "读取到的配置:" +
               "port=" + appConfig.getPort() +
               ", appName=" + appConfig.getAppName();
    }
}

2.2.2 Environment 对象(动态读取) ​

Spring内置的环境配置接口,可以动态获取配置。

基础用法 ​

java
package com.example.controller;

import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController {

    @Autowired
    private Environment env;

    @GetMapping("/config2")
    public String getConfig2() {
        // 获取配置,带默认值
        String port = env.getProperty("server.port", "8080");
        
        // 判断配置是否存在
        boolean hasKey = env.containsProperty("app.name");
        
        // 获取当前激活的环境
        String[] profiles = env.getActiveProfiles();
        
        return "port=" + port + ", activeProfile=" + profiles[0];
    }
}

常用方法 ​

方法说明
getProperty(key)获取配置值,返回String,不存在返回null
getProperty(key, defaultValue)获取配置,带默认值
getRequiredProperty(key)获取配置,不存在直接抛异常
containsProperty(key)判断配置是否存在
getActiveProfiles()获取当前激活的所有profile

适用场景 ​

  • 配置key是动态的,运行时才能确定
  • 工具类、非Spring管理的类中获取配置
  • 偶尔读取少量配置,不想专门写配置类

💡 注意:业务代码不要大量写env.getProperty(),会导致代码散乱。一组相关配置优先用@ConfigurationProperties。

2.2.3 @ConfigurationProperties 注解(批量绑定⭐企业推荐) ​

Spring Boot官方推荐方式,批量把一组配置绑定到Java对象,支持松散绑定、数据校验,企业项目首选。

基础示例 ​

  1. 配置文件application.yml
yaml
book:
  book-name: SpringBoot实战
  price: 79
  author: 广州华商职业学院
  tags:
    - Java
    - SpringBoot
  1. 配置类
java
@Data // 自动生成getter/setter,必须有!
@Component // 交给Spring容器管理
@ConfigurationProperties(prefix = "book") // 指定配置前缀
public class BookConfig {
    private String bookName;

    private Integer price;

    private String author;

    private List<String> tags;
}
  1. 使用
java
@RestController
public class BookController {

    @Autowired
    private BookConfig bookProperties;

    @GetMapping("/book")
    public BookConfig getBook() {
        return bookProperties;
    }
}

⚠️ 必须有setter方法!Spring通过setter注入属性。用Lombok的@Data会自动生成,不用手写。

image-20260916033337044

松散绑定(Relaxed Binding) ​

配置名和Java字段名不需要完全一致,自动匹配多种命名风格:

配置写法Java字段名能否匹配
book.bookNamebookName(驼峰)✅
book.book-namebookName(短横线kebab-case)✅
book.book_namebookName(下划线snake_case)✅
book.BOOK_NAMEbookName(全大写下划线)✅

✅ 官方推荐规范:配置文件用短横线式(book-name),Java代码用驼峰式(bookName)。

JSR303数据校验 ​

支持配置值合法性校验,项目启动时就校验,提前暴露配置错误,避免线上出问题。

  1. 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  1. 配置类加校验
java
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@Data
@Component
@Validated // 开启校验
@ConfigurationProperties(prefix = "user")
public class UserProperties {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @Min(value = 0, message = "年龄不能小于0")
    @Max(value = 150, message = "年龄不能大于150")
    private Integer age;

    @Email(message = "邮箱格式不正确")
    private String email;
}

配置不符合规则时,项目启动直接报错,把问题拦在启动阶段。

IDEA配置提示增强 ​

写自定义配置没有自动提示?加上配置处理器依赖,IDEA会自动补全:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

2.2.4 三种方式对比与选型 ​

对比项@ValueEnvironment@ConfigurationProperties
注入方式字段上注解对象注入类上注解,批量绑定
适用场景单个零散配置动态获取配置一组相关配置,结构化管理
松散绑定❌不支持—✅支持
JSR303校验❌不支持❌不支持✅支持
SpEL表达式✅支持❌不支持❌不支持
代码量配置多时繁琐适中配置多时简洁

📌 选型口诀:

  • 少量零散配置:用@Value
  • 动态key、工具类:用Environment
  • 一组相关配置、需要校验:优先用@ConfigurationProperties

2.3 自定义配置文件与配置类 ​

默认application.yml是全局配置,配置多了可以按模块拆分,也可以兼容老项目的XML配置。

2.3.1 @PropertySource 加载自定义properties配置 ​

把配置按模块拆分,加载自定义的.properties文件。

使用示例 ​

  1. 在resources下新建user.properties
user.id=1001
user.nickname=法外狂徒张三
  1. 配置类加载
java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@PropertySource("classpath:user.properties") // 加载自定义配置文件
@ConfigurationProperties(prefix = "user")
public class UserProperties {
    private String id;
    private String nickname;
}

注意事项 ​

  1. classpath:表示从类路径(resources目录)下查找
  2. 可以引入多个文件:@PropertySource({"classpath:a.properties", "classpath:b.properties"})
  3. ❗ 原生不支持加载YAML文件,只能加载properties。4.x推荐统一放在主yml中用前缀区分模块。

2.3.2 @ImportResource 引入XML配置 ​

兼容传统Spring的XML配置文件,老项目迁移用,新项目不推荐。

使用示例 ​

  1. resources下新建beans.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="myService" class="com.example.service.MyService"/>
</beans>
  1. 启动类引入XML
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:beans.xml") // 引入XML配置
public class Chapter02Application {
    public static void main(String[] args) {
        SpringApplication.run(Chapter02Application.class, args);
    }
}

适用场景 ​

  • 老项目迁移到Spring Boot,XML配置太多一时改不完
  • 第三方框架只提供XML配置方式

✅ 最佳实践:新项目全部用Java配置类(@Configuration + @Bean),不要写XML;老项目逐步迁移,不要长期混用。

2.3.3 @Configuration 配置类(Java配置,推荐⭐) ​

用Java代码做配置,替代XML配置文件,是Spring Boot推荐的方式。

基础用法 ​

java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // 标记这是一个配置类
public class MyConfig {

    // 把方法返回值注册到Spring容器,Bean名默认是方法名
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

等价于XML:<bean id="myService" class="com.example.service.MyService" />

@Bean进阶用法 ​

  1. 指定Bean名称
java
@Bean(name = "customService")
public MyService myService() {
    return new MyService();
}
  1. 指定初始化/销毁方法
java
@Bean(initMethod = "init", destroyMethod = "destroy")
public MyService myService() {
    return new MyService();
}
  1. 注入依赖
java
@Configuration
public class MyConfig {

    @Bean
    public UserDao userDao() {
        return new UserDao();
    }

    @Bean
    public UserService userService(UserDao userDao) {
        UserService service = new UserService();
        service.setUserDao(userDao);
        return service;
    }
}

​

一、简化目录结构示例 ​

src/main/java/com/example/demo/
├── DemoApplication.java      # 启动类
├── config/
│   └── MyConfig.java      # ⭐ Java配置类
├── service/
│   └── MyService.java     # 业务类
└── controller/
    └── TestController.java # 测试验证

二、核心代码 ​

1. 业务类 MyService.java ​

package com.example.demo.service;

public class MyService {
    public void sayHello() {
        System.out.println("Java配置类注册Bean成功!");
    }
}

2. 配置类 MyConfig.java(核心) ​

package com.example.demo.config;

import com.example.demo.service.MyService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // 标记:这是Java配置类
public class MyConfig {

    // @Bean:把方法返回值注册到Spring容器,Bean名默认=方法名
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

✅ 等价 XML:<bean id="myService" class="com.example.demo.service.MyService" />

3. 测试控制器 ​

package com.example.demo.controller;

import com.example.demo.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @Autowired // 自动注入注册好的Bean
    private MyService myService;

    @GetMapping("/testBean")
    public String test() {
        myService.sayHello();
        return "配置类测试成功,查看控制台";
    }
}

三、验证 ​

启动项目,访问:http://localhost:8080/testBean 控制台打印Java配置类注册Bean成功!,就说明配置生效。

Java配置类 vs XML配置 ​

对比项XML配置Java配置类
写法XML标签Java代码+注解
类型安全运行时才发现错误编译期就能检查
重构友好改类名需手动改XMLIDE重构自动修改
调试不方便可打断点调试
复杂逻辑不支持支持

🎯 面试题:Spring Boot推荐XML还是Java配置类? 答:推荐Java配置类(@Configuration + @Bean),类型安全、重构友好、便于调试。XML也支持,通过@ImportResource引入,主要用于兼容老项目。


2.4 Profile多环境配置(企业必备⭐⭐⭐) ​

项目从开发到上线,要经过开发、测试、生产多个环境,每个环境配置不一样。Profile机制实现「一套代码,多套配置」,切换环境只需改一个参数。

2.4.1 为什么需要多环境 ​

环境标识特点
开发环境dev本地开发调试,本地数据库、详细日志、热部署
测试环境test测试人员功能验证,测试数据库、模拟数据
生产环境prod线上正式运行,生产数据库、性能优化、安全加固

2.4.2 多文件多Profile(企业主流推荐) ​

每个环境一个独立配置文件,结构清晰,企业最常用。

命名规则 ​

application.yml          # 主配置:公共配置 + 指定激活环境
application-dev.yml      # 开发环境
application-test.yml     # 测试环境
application-prod.yml     # 生产环境

格式:application-{profile名}.yml

完整示例 ​

  1. 主配置application.yml
yaml
spring:
  application:
    name: chapter02-demo
  profiles:
    active: dev  # 默认激活开发环境
  1. 开发环境application-dev.yml
yaml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dev_db
    username: root
    password: 123456
logging:
  level:
    com.example: debug
  1. 生产环境application-prod.yml
yaml
server:
  port: 80
spring:
  datasource:
    url: jdbc:mysql://生产IP:3306/prod_db
    username: prod_user
    password: 生产密码
logging:
  level:
    com.example: info

四种切换方式(优先级从高到低) ​

  1. 命令行参数(生产部署最常用)
sh
java -jar myapp.jar --spring.profiles.active=prod
  1. JVM系统参数
java -Dspring.profiles.active=prod -jar myapp.jar
  1. 操作系统环境变量(Linux服务器常用)
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar
  1. 配置文件(开发时用)
yaml
spring:
  profiles:
    active: prod

🏢 企业最佳实践:

  • 代码里默认激活dev环境,方便开发
  • 生产环境用命令行参数指定,不把生产配置写死在代码里
  • 生产环境配置文件不提交Git,防止密码泄露

验证当前环境 ​

写个接口快速验证当前激活的环境:

java
@GetMapping("/profile")
public String getActiveProfile() {
    String[] profiles = environment.getActiveProfiles();
    return "当前激活环境:" + Arrays.toString(profiles);
}

2.4.3 @Profile注解(Bean级环境控制) ​

指定某个Bean只在特定环境下才注册生效。

示例 ​

  1. 定义接口
java
public interface SmsService {
    void sendMsg(String phone);
}
  1. 开发环境实现
java
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("dev") // 仅dev环境生效
public class DevSmsService implements SmsService {
    @Override
    public void sendMsg(String phone) {
        System.out.println("【开发模拟】发送短信到:" + phone);
    }
}
  1. 生产环境实现
java
@Component
@Profile("prod") // 仅prod环境生效
public class ProdSmsService implements SmsService {
    @Override
    public void sendMsg(String phone) {
        // 真实调用第三方短信接口
    }
}
  1. 使用
java
@RestController
public class SmsController {

    @Autowired
    private SmsService smsService; // 自动注入当前环境的实现

    @GetMapping("/sms")
    public String send() {
        smsService.sendMsg("13800138000");
        return "发送完成";
    }
}

进阶用法 ​

  • 取反:@Profile("!dev") 表示非dev环境才生效
  • 多环境:@Profile({"dev", "test"}) 表示dev和test环境都生效

2.4.4 单文件多Profile(了解) ​

同一个YAML文件用---分隔不同环境,适合个人小项目。

yaml
# 公共配置
spring:
  application:
    name: demo
  profiles:
    active: dev
---
# 开发环境
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
---
# 生产环境
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80

缺点:配置多时文件臃肿,多人协作容易冲突,适合个人小项目。


2.5 配置进阶:企业级实践 ​

2.5.1 配置优先级全解 ​

Spring Boot配置来源众多,优先级从高到低:

优先级来源说明
1(最高)命令行参数java -jar app.jar --server.port=8080
2JVM系统属性java -Dserver.port=8080 -jar app.jar
3操作系统环境变量服务器上配置的环境变量
4外部配置文件JAR包外config目录下的配置
5内部配置文件JAR包内resources下的配置
6@PropertySource引入的配置自定义加载的配置文件
7(最低)框架默认值Spring Boot自动配置的默认值

🛠 排查配置不生效第一步:先检查有没有更高优先级的配置覆盖了!

2.5.2 敏感信息处理 ​

生产环境数据库密码、第三方密钥等敏感信息,不能明文写在配置文件里,更不能提交Git。

常见处理方案 ​

  1. 环境变量(最简单) 配置文件引用环境变量:
spring:
  datasource:
    password: ${DB_PASSWORD}

服务器上设置环境变量:

export DB_PASSWORD=生产密码
  1. 配置中心(推荐) 用Nacos、Apollo等配置中心统一管理,敏感信息加密存储、权限控制、动态刷新。微服务阶段常用。
  2. 配置加密(jasypt) 配置文件里写加密后的密文,启动时用密钥解密。适合配置文件需要随项目分发的场景。

⚠️ 安全红线:绝对不要把生产环境密码提交到Git! 即使删除文件,历史记录里依然存在。一旦泄露立即修改密码。

2.5.3 配置中心简介 ​

项目多了之后,配置分散在各个项目里管理困难,配置中心解决统一管理、动态刷新、权限控制、版本管理、加密存储等问题。

常见配置中心:

  • Nacos:阿里巴巴出品,功能全,配置中心+注册中心,国内应用最广
  • Apollo:携程出品,治理能力强,大型企业用得多
  • Spring Cloud Config:Spring官方,轻量,配合Git使用

了解即可,微服务阶段会详细学习,先建立概念。


2.6 常见问题排查清单 ​

1. 配置不生效 ​

排查步骤:

  1. 检查文件名:必须是application.yml / application.properties,拼写错误、大小写错误都不行
  2. 检查位置:默认必须在resources根目录
  3. 检查YAML语法:冒号后有空格、只用空格缩进、同一层级对齐(最常见)
  4. 检查优先级:有没有更高优先级的配置覆盖
  5. 检查拼写:注意松散绑定规则,大小写敏感
  6. 开启debug模式,查看自动配置报告

2. @ConfigurationProperties不生效 ​

排查:

  1. 类上有没有@Component/@Configuration,必须被Spring管理
  2. prefix是否和配置前缀一致
  3. 字段名和配置名是否匹配(松散绑定规则)
  4. 有没有setter方法(Lombok @Data会自动生成)
  5. 启动类有没有扫描到配置类

3. 多环境切换不生效 ​

排查:

  1. profile名称拼写是否正确(dev/test/prod)
  2. 配置文件名是否正确:application-dev.yml,横杠、后缀不要写错
  3. 激活配置是否写在主配置文件里
  4. 有没有更高优先级的激活方式(比如命令行参数)

4. 配置中文乱码 ​

解决:

  1. IDEA设置:Settings → Editor → File Encodings,Properties文件编码设为UTF-8,勾选「Transparent native-to-ascii conversion」
  2. 配置文件指定编码:
spring:
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

5. @Value注入失败 ​

排查:

  1. 类有没有交给Spring管理(加@Component)
  2. 配置key是否存在,有没有拼写错误
  3. 是不是写成了@Value("name"),漏掉了$和大括号
  4. 配置文件位置不对

2.7 本章作业(动手实操+思考题) ​

一、基础必做题(全员必做,必须跑通验证) ​

作业1:配置格式转换 ​

题目:将下面properties配置转换成标准YAML格式,保存为application.yml

properties
server.port=8081
spring.application.name=chapter02-homework
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/homework
spring.datasource.username=root
spring.datasource.password=root123
book.book-name=SpringBoot入门实战
book.price=68
book.tags=Java,SpringBoot,后端

要求:

  • 缩进正确,层级清晰
  • 用在线转换工具校验格式正确性
  • 启动项目,验证端口变为8081

作业2:三种读取配置练习 ​

题目:

  1. 在application.yml中配置自定义student前缀的配置:姓名、年龄、邮箱、爱好(数组)
  2. 分别用三种方式读取配置:
    • @Value读取姓名,设置默认值
    • Environment动态读取年龄
    • @ConfigurationProperties批量绑定全部字段,加上JSR303校验
  3. 编写Controller接口,返回读取到的全部配置数据
  4. 浏览器访问验证三种方式都能正确读取

验收标准:

  • 接口返回所有配置值正确
  • 故意写错邮箱格式,项目启动报错,证明校验生效

作业3:Java配置类练习 ​

题目:

  1. 创建DemoUtil工具类,编写一个printInfo()方法
  2. 用@Configuration + @Bean的方式将DemoUtil注册到Spring容器
  3. 编写Controller注入调用,验证Bean成功注册

验收标准:

  • 访问接口,控制台打印printInfo的内容

作业4:多环境配置练习 ​

题目:

  1. 创建三套环境配置:dev(端口8080)、test(端口8081)、prod(端口80)
  2. 每套环境配置不同的数据库连接url
  3. 修改spring.profiles.active切换环境,观察启动端口和配置变化
  4. 项目打成JAR包,用命令行参数切换到prod环境,验证端口变为80

验收标准:

  • 切换环境,启动端口对应变化
  • 命令行启动JAR包,prod环境生效

作业5:@Profile环境切换练习 ​

题目:

  1. 定义FileUploadService接口
  2. 编写dev环境实现:模拟本地上传,打印日志
  3. 编写prod环境实现:模拟OSS云存储上传,打印日志
  4. 切换环境,验证注入的实现类自动切换

验收标准:

  • dev环境访问接口,返回“本地上传”
  • prod环境访问接口,返回“OSS上传”

二、进阶选做题(学有余力完成) ​

选做1:外置配置文件验证 ​

  1. 将项目打成JAR包
  2. 在JAR同级创建config目录,放入外部application.yml
  3. 修改外部配置端口为9090
  4. 启动JAR包,验证外部配置优先级更高

选做2:环境变量引用配置 ​

  1. 数据库密码使用系统环境变量${DB_PASSWORD}读取
  2. 在IDEA启动配置里设置环境变量
  3. 启动项目验证能正常读取

选做3:配置绑定松散绑定验证 ​

  1. 配置文件用短横线写法user.nick-name
  2. Java字段用驼峰nickName
  3. 验证能正确读取

三、思考题(面试/笔试) ​

  1. @Value和@ConfigurationProperties有什么区别?分别适用于什么场景?
  2. Spring Boot配置优先级从高到低有哪些?配置不生效的排查思路是什么?
  3. Profile多环境有哪几种切换方式?优先级是怎样的?企业最佳实践是什么?
  4. YAML语法有哪些新手常见坑?
  5. 为什么生产环境的敏感信息不能提交到Git?列举两种处理方案。
  6. Spring Boot推荐XML配置还是Java配置类?为什么?

2.8 本章小结 ​

  1. 配置文件:properties和YAML两种格式,YAML结构清晰是主流,重点注意缩进和空格语法坑
  2. 读取配置:@Value适合单个配置;Environment适合动态读取;@ConfigurationProperties批量绑定+校验,企业首选
  3. 自定义配置:@PropertySource加载properties;@ImportResource兼容XML;@Configuration+@BeanJava配置是推荐方式
  4. 多环境配置:多文件多Profile是企业主流;@Profile控制Bean级环境;命令行参数激活优先级最高
  5. 企业实践:外置配置文件、配置优先级、敏感信息安全规范
  6. 排错能力:能独立排查配置不生效、读取失败等常见问题

下一章:Spring Boot Web开发进阶:拦截器、全局异常、文件上传、参数校验、跨域处理。

基于 Vite 强力驱动 | 纯静态轻量托管